/*
 * Vector.cpp
 *
 *  Created on: 21-11-2010
 *      Author: Przemek
 */

#include "geometry/Vector.hpp"
#include "utils/DivisionByZeroException.hpp"
#include "utils/MathUtils.hpp"
#include "pch.hpp"

Vector::Vector(float x, float y) :
	x(x), y(y)
{
}

Vector::Vector(int x, int y) :
	x(static_cast<float> (x)), y(static_cast<float> (y))
{

}

Vector::Vector(const Vector& other) :
	x(other.x), y(other.y)
{
}

float Vector::getX() const
{
	return x;
}

void Vector::setX(float x)
{
	this->x = x;
}

void Vector::setX(int x)
{
	this->x = static_cast<float> (x);
}

float Vector::getY() const
{
	return y;
}

void Vector::setY(float y)
{
	this->y = y;
}

void Vector::setY(int y)
{
	this->y = static_cast<float> (y);
}

void Vector::set(const Vector& other)
{
	operator=(other);
}

float Vector::getSquaredLength() const
{
	return (x * x + y * y);
}

float Vector::getLength() const
{
	return sqrtf(getSquaredLength());
}

float Vector::getAngleInRadians() const
{
	return atan2(y, x);
}

float Vector::getCos(const Vector& other) const
{
	float product = x * other.x + y * other.y;
	return product / (getLength() * other.getLength());
}

Vector Vector::normalize() const
{
	return (*this) / getLength();
}

Vector Vector::operator-() const
{
	return Vector(-x, -y);
}

Vector Vector::operator+(const Vector& other) const
{
	return Vector(x + other.x, y + other.y);
}

Vector Vector::operator-(const Vector& other) const
{
	return Vector(x - other.x, y - other.y);
}

Vector Vector::operator*(const float value) const
{
	return Vector(x * value, y * value);
}

Vector Vector::operator/(const float value) const
{
	if(MathUtils::isNearZero(value))
	{
		throw DivisionByZeroException();
	}
	return Vector(x / value, y / value);
}

Vector& Vector::operator+=(const Vector& other)
{
	x += other.x;
	y += other.y;

	return *this;
}

Vector& Vector::operator-=(const Vector& other)
{
	x -= other.x;
	y -= other.y;

	return *this;
}

Vector& Vector::operator*=(const float value)
{
	x *= value;
	y *= value;

	return *this;
}

Vector& Vector::operator/=(const float value)
{
	if(MathUtils::isNearZero(value))
	{
		throw DivisionByZeroException();
	}

	x /= value;
	y /= value;

	return *this;
}

Vector& Vector::operator=(const Vector& other)
{
	if(this != &other)
	{
		x = other.x;
		y = other.y;
	}

	return *this;
}

bool Vector::operator==(const Vector& other) const
{
	return (MathUtils::isEqual(x, other.x) && MathUtils::isEqual(y, other.y));
}

bool Vector::operator!=(const Vector& other) const
{
	return !(operator==(other));
}
